perm filename HOST.FAI[S,NET]9 blob
sn#828471 filedate 1986-11-12 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00006 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002 A B C X Y P PDLEN HSTSID HSTFN1 HSTVRS HSTDIR HSTDEV HSTWHO HSTDAT HSTTIM NAMPTR SITPTR NETPTR NTNPTR HDRLEN NETNUM NTLNAM NTRTAB NETLEN ADDADR ADLSIT ADRCDR ADLXXX ADRSVC SVLCNT SVRCDR SVLFLG SVRNAM SVCARG ADDLEN STLNAM STRADR STLSYS STRMCH STLFLG STFSRV STFGWY SITLEN NMLSIT NMRNAM NAMLEN NNLNET NNRNAM NTNLEN NT$NUM NE%UNT NE%STR NN%IP NW%ARP NW%SI NW%SU HSTFIL HSTPPN
C00015 00003 START GETCOM FLSINP HSTCOM CMDSCN PROMPT DOCMD HSTLUP GOTHST GETNUM GETNU1 GETNU2 GETNU3 GETNU4 GETNU5 GETNU6 NOTIPH HSTLUZ ALPHST DOSRCH SEARCH SRCLT SRCGT SRCDUN SRCDU1 SRCDU2 COMPAR PRINT OFFNAM NAMLP NAMDUN MCHTYP ENDNIC
C00029 00004 GETHST ATTHST ATTHS0 ATTHS2 ATTCRE ATTMUL ATTUPP ATTLOW ATTERR MXATTE HSGNAM MAPHS2 MAPHST MAPHS0 MAPHS4 MAPHS3
C00038 00005 HSTNUM HSTNUS HSTNU1
C00040 00006 SWINIR SWINR1 SWINR2 SWINIP SWINP1 PRHNUM PRHNIP PRDECP PRDEC PROCT PRLOOP PDL MONCMP NOHOST PASS1 EXACT HSTADR HSTTOP HSTEXT CRLF CPOPJ2 CPOPJ1 CPOPJ
C00045 ENDMK
C⊗;
;⊗ A B C X Y P PDLEN HSTSID HSTFN1 HSTVRS HSTDIR HSTDEV HSTWHO HSTDAT HSTTIM NAMPTR SITPTR NETPTR NTNPTR HDRLEN NETNUM NTLNAM NTRTAB NETLEN ADDADR ADLSIT ADRCDR ADLXXX ADRSVC SVLCNT SVRCDR SVLFLG SVRNAM SVCARG ADDLEN STLNAM STRADR STLSYS STRMCH STLFLG STFSRV STFGWY SITLEN NMLSIT NMRNAM NAMLEN NNLNET NNRNAM NTNLEN NT$NUM NE%UNT NE%STR NN%IP NW%ARP NW%SI NW%SU HSTFIL HSTPPN
TITLE HOST
;This program is adapted from the old HOST.MID, which read the HOSTS1.BIN
;file, and from various code in NETWRK.FAI. NETWRK isn't inserted directly,
;because we want to do slightly different things in searching for host names.
Comment ⊗
12 Nov 86 JJW Changed MAPHST to GETHST, which calls ATTHST to attach
high segment and then copies table into low segment.
⊗ ;end of history
A←12 ;Our AC's don't interfere with NETWRK's
B←13
C←14
X←15
Y←16
P←17
PDLEN←←20
;The format of the host table binary file is:
HSTSID←←0 ; wd 0 SIXBIT /HOSTS3/
HSTFN1←←1 ; wd 1 SIXBIT FN1 of source file (eg HOSTS)
HSTVRS←←2 ; wd 2 SIXBIT FN2 of source file (TNX: version #)
HSTDIR←←3 ; wd 3 SIXBIT directory name of source file (eg SYSENG)
HSTDEV←←4 ; wd 4 SIXBIT device name of source file (eg AI)
HSTWHO←←5 ; wd 5 SIXBIT login name of person who compiled this
HSTDAT←←6 ; wd 6 SIXBIT Date of compilation as YYMMDD
HSTTIM←←7 ; wd 7 SIXBIT Time of compilation as HHMMSS
NAMPTR←←10 ; wd 10 Fileaddress of NAME table.
SITPTR←←11 ; wd 11 Fileaddress of SITE table.
NETPTR←←12 ; wd 12 Fileaddress of NETWORK table.
NTNPTR←←13 ; wd 13 Fileaddress of NETNAME table.
;....expandable....
HDRLEN←←14 ; length of header
; NETWORK table
; wd 0 Number of entries in table.
; wd 1 Number of words per entry. (2)
; This table contains one entry for each known network.
; It is sorted by network number.
; Each entry contains:
NETNUM←←0 ; wd 0 network number (full netaddr)
NTLNAM←←1 ; wd 1 LH - fileaddr of ASCIZ name of network
NTRTAB←←1 ; wd 1 RH - fileaddr of network's ADDRESS table
NETLEN←←2
; ADDRESS table(s)
; wd 0 Number of entries in table.
; wd 1 Number of words per entry. (3)
; There is one of these tables for each network. It contains entries
; for each site attached to that network, sorted by network address.
; These tables are used to convert a numeric address into a host name.
; Also, the list of network addresses and services for a site is stored
; within these tables.
; Each entry contains:
ADDADR←←0 ; wd 0 Network address of this entry, in HOSTS3 fmt.
ADLSIT←←1 ; wd 1 LH - fileaddr of SITE table entry
ADRCDR←←1 ; wd 1 RH - fileaddr of next ADDRESS entry for this site
; 0 = end of list
ADLXXX←←2 ; wd 2 LH - unused
ADRSVC←←2 ; wd 2 RH - fileaddr of services list for this address
; 0 = none, else points to SERVICE node of format:
SVLCNT←←0 ; <# wds>,,<fileaddr of next, or 0>
SVRCDR←←0
SVLFLG←←1 ; <flags>,,<fileaddr of svc name>
SVRNAM←←1
SVCARG←←2 ; <param1> ? <param2> ? ...
ADDLEN←←3
; SITE table
; wd 0 Number of entries in table.
; wd 1 Number of words per entry. (3)
; This table contains entries for each network site,
; not sorted by anything in particular. A site can have more
; than one network address, usually on different networks.
; This is the main, central table.
; Each entry looks like:
STLNAM←←0 ; wd 0 LH - fileaddr of official host name
STRADR←←0 ; wd 0 RH - fileaddr of first ADDRESS table entry for this
; site. Successive entries are threaded
; together through ADRCDR.
STLSYS←←1 ; wd 1 LH - fileaddr of system name (ITS, TIP, TENEX, etc.)
; May be 0 → not known.
STRMCH←←1 ; wd 1 RH - fileaddr of machine name (PDP10, etc.)
; May be 0 → not known.
STLFLG←←2 ; wd 2 LH - flags:
STFSRV←←400000 ; 4.9 1 → server site (has FTP or TELNET)
STFGWY←←200000 ; 4.8 1 → Internet Gateway site (HOSTS3 only)
SITLEN←←3
; NAMES table:
; wd 0 Number of entries
; wd 1 Number of words per entry. (1)
; This table is used to convert host names into network addresses. It
; contains entries sorted alphabetically by host name.
NMLSIT←←0 ; wd 0 LH - fileaddr of SITE table entry for this host.
NMRNAM←←0 ; wd 0 RH - fileaddr of host name
; This name is official if NMRNAM = STLNAM of NMLSIT.
NAMLEN←←1
; NETNAME table:
; wd 0 Number of entries
; wd 1 Number of words per entry. (1)
; This table is used to convert network names into network numbers. It
; contains entries sorted alphabetically by network name, exactly as
; for the NAMES table. Although the symbols below are different (in order
; to make semantic distinctions), programs can depend on the fact
; that the NETNAME table format is identical to that of the NAMES table.
NNLNET←←0 ; wd 0 LH - fileaddr of NETWORK table entry for this host.
NNRNAM←←0 ; wd 0 RH - fileaddr of network name
NTNLEN←←1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;; HOSTS3 Network Address Format ;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
comment |
HOSTS3 network address format:
4.9-4.6 - 4 bits of format type, which specify interpretation of
the remaining 32 bits.
IN 0000 - Internet address (handles ARPA, RCC, LCS)
4.5-1.1 - 32 bits of IN address.
UN 0001 - Unternet address. Same format, but not part of Internet.
4.5-3.7 - HOSTS3-defined network number (1st 8-bit byte)
3.6-1.1 - address value in next 24 bits.
This handles CHAOS and any local nets. The network
numbers are unique within the HOSTS3 table but
don't necessarily mean anything globally, as do
Internet network numbers.
0011 - String address.
4.5-3.7 - HOSTS3-defined network number (1st 8-bit byte)
3.6-3.1 - 0
2.9-1.1 - address of ASCIZ string in file/process space
Note that the "network number" for all of these formats is located in
the same place. However, for fast deciphering of the entire range of
possibilities, one could simply consider all of the high 12 bits as the
network number. Beware of the Internet class A, B, and C formats, though;
the only truly general way to compare network numbers is to use their
masked 36-bit values, although simpler checks are OK for specific nets.
For this reason (among others) network numbers are represented by
full 36-bit values with the "local address" portion zero.
The 4-bit "String address" value is much more tentative than the IN or UN
values. Bit 4.9, the sign bit, is being reserved as usual for the possible
advent of a truly spectacular incompatible format.
|
NT$NUM←←301400 ;Byte pointer to network number (high 12 bits)
NE%UNT←←<040000,,0> ;Escape bit indicating "Unternet" type address
NE%STR←←<100000,,0> ;Escape bit indicating "string" type address
NN%IP←←<740000,,0> ;host number bits that are off for all IP addresses
NW%ARP←←<12⊗=24> ;HOSTS3 uses full word network # values
NW%SI←←44⊗=24 ;Internet address of SU-NET-TEMP
NW%SU←←NE%UNT+NW%SI ;"Unternet" used for Stanford Ethernet
DEFINE GETNET(AC,ADDR)<
IFDIF <ADDR><><MOVE AC,ADDR>
TLNN AC,(17⊗=32) ; Check for non-Internet type addrs
TLNN AC,(1⊗=31) ; Internet address, see if class A net
TDZA AC,[77,,-1] ; Unternet or class A, zap low 3 octets
TLNN AC,(1⊗=30) ; Class B or C, see which.
TRZA AC,177777 ; Class B network, zap low 2 octets
TRZ AC,377 ; Class C net, only zap 1 low octet
>;GETNET
HSTFIL: SIXBIT/HOSTS3/ ;filename and extension of binary file
SIXBIT/BIN/
HSTPPN: SIXBIT/HSTNET/ ;PPN of binary file
;⊗ START GETCOM FLSINP HSTCOM CMDSCN PROMPT DOCMD HSTLUP GOTHST GETNUM GETNU1 GETNU2 GETNU3 GETNU4 GETNU5 GETNU6 NOTIPH HSTLUZ ALPHST DOSRCH SEARCH SRCLT SRCGT SRCDUN SRCDU1 SRCDU2 COMPAR PRINT OFFNAM NAMLP NAMDUN MCHTYP ENDNIC
START: CAI
RESET
SETZM MONCMP
MOVE P,[IOWD PDLEN,PDL]
PUSHJ P,GETHST ;Map host table in core
RESCAN A
JUMPE A,PROMPT
GETCOM: INCHRS X
JRST PRMPT0
CAIE X," " ;Skip whitespace
CAIN X,11
JRST GETCOM
CAIE X,"H" ;Check for HOST command
CAIN X,"h"
JRST HSTCOM
FLSINP: INCHRS X
JRST PRMPT0
CAIE X,175
CAIN X,12
JRST PRMPT0
JRST FLSINP
HSTCOM: OUTSTR CRLF
CMDSCN: INCHRS X
JRST GOTHST
CAIE X,175
CAIN X,12
JRST GOTHST ;No command argument
CAIE X," "
JRST CMDSCN
SETOM MONCMP
JRST DOCMD
PRMPT0: GETPPN A,
CAME A,['100100']
PROMPT: SKIPE MONCMP
EXIT 1,
OUTSTR [ASCIZ/
Host name or number: /]
DOCMD: SETZM HSTEXT
MOVE Y,[POINT 7,HSTEXT]
HSTLUP: INCHWL X
ANDI X,177
CAIN X,15
INCHWL X
CAIE X,175
CAIN X,12
JRST GOTHST
IDPB X,Y
JRST HSTLUP
GOTHST: SETZ X,
IDPB X,Y
;Here with input text string in HSTEXT.
SKIPN HSTEXT
JRST PRMPT0
MOVE Y,[POINT 7,HSTEXT] ;Start at beginning of text
ILDB X,Y ;Now see if we got a name or a number
CAIL X,"0"
CAILE X,"9"
JRST ALPHST ;Alphabetic host specification
PUSHJ P,SWINIP ;Get host number
JRST NOTIPH ;Not an IP host number
JUMPN X,HSTLUZ
MOVE 0,B ;Set up for HSTNUM
GETNUM: PUSHJ P,HSTNUM ;Look up the number
JRST GETNU2 ;Not found
GETNU1: HLRZ 6,STLNAM(7) ;Get official name
ADD 6,HSTADR
OUTSTR (6)
PUSHJ P,OFFNAM ;Finish typing host info
JRST PROMPT
GETNU2: HLRZ 0,B ;Get LH of host number
ANDI 0,777700 ;Just class-A network part
CAIN 0,(NW%SU) ;Stanford PUP address?
JRST GETNU4 ;Yes, convert to IP
CAIN 0,(NW%SI) ;Or Stanford IP?
JRST GETNU5 ;Yes, convert to PUP
GETNU3: OUTSTR [ASCIZ/Unknown host
/]
JRST PROMPT
GETNU4: LDB 0,[POINT 8,B,27] ;Subnet number from PUP address
LSH 0,=8 ;Position for IP address
JRST GETNU6
GETNU5: LDB 0,[POINT 8,B,19] ;Subnet number from IP address
GETNU6: DPB 0,[POINT 16,B,27] ;Store 2nd and 3 bytes
TLC B,(NW%SU≠NW%SI) ;Change to the other network
MOVE 0,B
PUSHJ P,HSTNUM ;And look that up
JRST GETNU3 ;Not there either
JRST GETNU1 ;Matched, sort of, so tell the user
;Here with a non-IP host number in A (octal) and B (decimal).
NOTIPH: JUMPE X,[OUTSTR [ASCIZ/Incomplete host number specification
/]
JRST PROMPT]
CAIN X,"/" ;BBN style number?
JRST [ CAILE B,377
SETO B,
PUSH P,B
ILDB X,Y ;Check numericness
CAIL X,"0"
CAILE X,"9"
JRST HSTLUZ
PUSHJ P,SWINIR
SKIPN B
SETZM (P)
POP P,A ;A←host, B←IMP
JUMPN X,HSTLUZ
LSH A,=16
ADDI A,(B)
TLO A,(NW%ARP) ;Set network
MOVE 0,A
JRST GETNUM]
CAIN X,"#" ;XEROX style number
JRST [ SKIPLE A
CAILE A,377
JRST HSTLUZ
PUSH P,A
ILDB X,Y ;Check numericness
CAIL X,"0"
CAILE X,"9"
JRST HSTLUZ
PUSHJ P,SWINIR
POP P,B ;B←subnet, A←host
JUMPN X,HSTLUZ
SKIPLE A
CAILE A,377
JRST HSTLUZ
LSH B,=8
ADDI B,(A)
TLO B,(NW%SU) ;Set network
MOVE 0,B
JRST GETNUM]
HSTLUZ: OUTSTR [ASCIZ/Bad host number format
/]
JRST PROMPT
;Here with an alphabetic host name.
ALPHST: SETOM NOHOST ;Indicate no host found so far
PUSHJ P,DOSRCH
SKIPE NOHOST ;Did we print anything?
OUTSTR [ASCIZ/Unknown host name
/]
JRST PROMPT
;Set up various AC's for search.
DOSRCH: MOVE 0,[POINT 7,HSTEXT]
MOVE 1,HSTADR
MOVE 1,NAMPTR(1)
ADD 1,HSTADR ;Address of NAMES table
HRLI 1,2(1) ;<first entry>,,<addr of table>
ADD 1,(1) ;<first entry>,,<last entry>+1
PUSH P,1 ;Save for use in SRCDUN
SUBI 1,1 ;<first entry>,,<last entry>
SETZ 3, ;No partial match yet
;Host name search. AC's during search hold the following:
; 0: byte pointer to source string
; 1: <beginning>,,<ending> of current range in NAMES table
; 2: current entry in NAMES table being tested
; 3: -1 if a partial match found
SEARCH: HLRZ 2,1 ;Beginning of current range
CAILE 2,(1) ;Beyond end?
JRST SRCDUN ;Yes, search done
ADDI 2,(1) ;Add beginning and ending
LSH 2,-1 ;Compute midpoint
HRRZ 7,NMRNAM(2)
ADD 7,HSTADR ;Pointer for this entry
HRLI 7,440700
MOVE 6,0 ;Copy of source pointer
PUSHJ P,COMPAR
JRST SRCGT
JRST SRCLT
JRST [ ADJSP P,-1 ;Exact match!
PUSHJ P,PRINT
JRST UNFLAG]
SETO 3, ;Partial match
;Here if source string less than table entry.
SRCLT: HRRI 1,-1(2) ;Set end of range to before entry
JRST SEARCH
;Here if source string greater than table entry.
SRCGT: HRLI 1,1(2) ;Set beginning of range to after entry
JRST SEARCH
;Here when binary search done. 2 contains first name that might match.
;Scan forward and compare until no more match, to get range of names.
SRCDUN: POP P,1 ;Get back <first entry>,,<last entry+1>
JUMPE 3,CPOPJ ;Jump if no match
PUSH P,2 ;Remember first entry
SUBM 2,1 ;- <Max # of entries to check>
HRL 2,1 ;Make AOBJN ptr
SRCDU1: HRRZ 7,NMRNAM(2)
ADD 7,HSTADR ;Pointer for this entry
HRLI 7,440700
MOVE 6,0 ;Copy of source pointer
PUSHJ P,COMPAR
JRST SRCDU2
JRST SRCDU3 ;Done
HALT . ;Exact match can't happen here!
SRCDU2: AOBJN 2,SRCDU1 ;Loop unless hit end of table
SRCDU3: SUB 2,(P) ;# of matching entries
MOVNI 2,(2)
HRLM 2,(P) ;AOBJN ptr
MOVE 2,(P)
PUSHJ P,PRINT
AOBJN 2,.-1
POP P,2
PUSHJ P,UNFLAG
AOBJN 2,.-1
POPJ P,
;Subroutine to compare two names given by byte pointers in 6 and 7.
;Returns: +1 if (6) .gt. (7)
; +2 if (6) .lt. (7) and is not a partial match
; +3 if (6) matches (7) exactly
; +4 if (6) matches a substring of (7)
;ACs 10 and 11 hold the most recent characters read from each string.
COMPAR: ILDB 10,6 ;Get next byte from each string
ILDB 11,7
JUMPE 10,[JUMPE 11,CPOPJ2 ;Exact match
AOS (P) ;Partial match
JRST CPOPJ2]
JUMPE 11,CPOPJ ;Partial match the other way
CAIL 10,"a" ;Use upper case for comparisons
SUBI 10,40
CAIL 11,"a"
SUBI 11,40
CAIGE 10,(11)
AOSA (P)
CAILE 10,(11)
POPJ P,
JRST COMPAR ;Characters match, keep comparing
;Here to print information for a host. Call with name table entry address in 2.
PRINT: SETZM NOHOST ;We now have found a match
HRRZ 5,NMRNAM(2)
ADD 5,HSTADR
HLRZ 7,NMLSIT(2)
ADD 7,HSTADR
MOVSI 10,1 ;Pseudo-flag
TDNE 10,STLFLG(7) ;Have we shown it already?
POPJ P, ;Yes
IORM 10,STLFLG(7) ;Set pseudo-flag when we show a site
HLRZ 6,STLNAM(7)
ADD 6,HSTADR
OUTSTR (5)
CAIN 5,(6)
JRST OFFNAM ;Official name
OUTSTR [ASCIZ/ is a nickname for /]
OUTSTR (6)
OUTSTR [ASCIZ/, which/]
;Enter here from GETNUM (host lookup by number) with site table entry in 7.
OFFNAM: OUTSTR [ASCIZ/ is number /]
HRRZ 6,STRADR(7)
NAMLP: ADD 6,HSTADR
MOVE X,ADDADR(6)
PUSHJ P,PRHNUM
HRRZ 6,ADRCDR(6)
JUMPE 6,NAMDUN
OUTSTR [ASCIZ/, /]
JRST NAMLP
NAMDUN: OUTSTR [ASCIZ/,
a /]
SKIPL STLFLG(7)
SKIPA 10,[[ASCIZ/user /]]
MOVEI 10,[ASCIZ/server /]
OUTSTR (10)
HRRZ 6,STRMCH(7)
JUMPE 6,[ OUTSTR [ASCIZ/unknown/]
JRST MCHTYP]
ADD 6,HSTADR
OUTSTR (6)
MCHTYP: OUTSTR [ASCIZ/ machine running /]
HLRZ 6,STLSYS(7)
JUMPE 6,[ OUTSTR [ASCIZ/an unknown operating system.
/]
POPJ P,]
ADD 6,HSTADR
OUTSTR (6)
ENDNIC: OUTSTR [ASCIZ/.
/]
POPJ P,
UNFLAG: HRRZ 5,NMRNAM(2)
ADD 5,HSTADR
HLRZ 7,NMLSIT(2)
ADD 7,HSTADR
MOVSI 10,1 ;Pseudo-flag
ANDCAM 10,STLFLG(7) ;Turn it off
POPJ P,
;⊗ GETHST ATTHST ATTHS0 ATTHS2 ATTCRE ATTMUL ATTUPP ATTLOW ATTERR MXATTE HSGNAM MAPHS2 MAPHST MAPHS0 MAPHS4 MAPHS3
; GETHST -- Map host table into core
; Call: PUSHJ 17,GETHST
; <return>
; Smashes 0, 1, 2, and 3.
;Adapted from ATTHST and MAPHST in NETWRK. (Removing fancy error recovery,
;mostly.) We'd like to use the upper segment to avoid reading the host
;table from disk, but need to modify it, so we can't share it with other
;jobs. The solution is to copy it into our lower segment.
GETHST: PUSHJ 17,ATTHST ;Attach host table upper segment
SKIPN 1,HSTTOP ;End address of table, if we read it
HRRZ 1,JOBHRL↑ ;Else make a conservative estimate
SUB 1,HSTADR ;Length of table
ADD 1,JOBFF↑ ;New size for low segment
CAILE 1,377777 ;Will it fit?
JRST 4,.-1 ;No. (If this ever happens, use ordinary MAPHST.)
MOVE 2,JOBFF ;Remember old JOBFF
MOVEM 1,JOBFF ;Save new JOBFF
CORE 1, ;Expand low segment
JRST 4,.-1
MOVE 1,JOBFF
MOVEM 1,HSTTOP
HRL 2,HSTADR ;Set up BLT to copy from old HSTADR
HRRZM 2,HSTADR ;Save new HSTADR before we clobber AC 2
BLT 2,-1(1) ;Copy the table
MOVEI 0,0
CORE2 0, ;Flush high segment
JFCL
POPJ 17,
;ATTHST -- Attach to upper segment that has the host table in it,
; or create one if necessary.
;Call: PUSHJ 17,ATTHST
; <return>
;Preserves ALL ACs.
ATTHST: PUSH 17,3 ;preserve all ACs
MOVE 3,HSGNAM ;get upper segment name
ATTHS0: ATTSEG 3, ;try to attach to segment
JRST ATTHS2 ;failed, see why
MOVEI 3,400000
MOVEM 3,HSTADR ;set host table address
POP 17,3
POPJ 17,
ATTHS2: HLLM 3,-1(17) ;save error code's left half
ANDI 3,-1 ;just error code
CAIL 3,MXATTE ;reasonable error?
MOVEI 3,MXATTE ;no
JRST @ATTERR(3) ;dispatch on error
;Create upper segment and read host table into it.
ATTCRE: PUSH 17,0
PUSH 17,1
PUSH 17,2
PUSHJ 17,MAPHS2 ;read host table into new upper segment, AC 3 already saved
MOVEI 1,1
SETUWP 1, ;write protect upper segment
JFCL ;error should never happen
MOVE 1,HSGNAM
SETNM2 1, ;rename it so others can share it
JFCL ;error should never happen
POP 17,2
POP 17,1
POP 17,0
POP 17,3
POPJ 17,
;Attach one of multiple uppers with same name
ATTMUL: HLRZ 3,-1(17) ;job number of one job with given name
JRST ATTHS0 ;try again
ATTUPP: JRST 4,.
ATTLOW: JRST 4,.
ATTERR: ATTCRE ;protection violation, create new segment
ATTMUL ;multiple upper segments, attach one
ATTCRE ;no such upper segment job number
ATTCRE ;no such upper segment job name
ATTUPP ;already have an upper
ATTLOW ;lower segment is too big
MXATTE←←.-ATTERR
HSGNAM: SIXBIT/HOSTS!/ ;name of upper segment
; MAPHST -- Map host table into core
; Call: PUSHJ 17,MAPHST
; <return>
; Smashes 0, 1, 2, and 3.
MAPHS2: HRROS (17) ;indicate want host table in new upper segment
JRST MAPHS0
MAPHST: HRRZS (17) ;indicate want host table in lower segment
MAPHS0: INIT 17
('DSK')
0
JRST 4,.-3
DMOVE 0,HSTFIL
MOVE 3,HSTPPN
LOOKUP 0
JRST 4,.-1
MOVS 0,3 ;unswap file length
MOVN 0,0 ;make file length positive
SKIPGE (17) ;going into upper?
JRST MAPHS3 ;yes
MOVE 2,JOBFF↑ ;place to put table
ADDB 0,JOBFF↑ ;get address of highest addr we need
MOVEM 0,HSTTOP
CORE 0, ;get more core from system maybe
JRST 4,.-1
MAPHS4: MOVE 0,3 ;negative length in LH
HRRI 0,-1(2) ;compute IOWD to read host table in
MOVEI 1,0
INPUT 0 ;read whole host table
MOVE 0,(2) ;get first word of host table
CAME 0,HSTFIL
JRST 4,.-1
MOVEM 2,HSTADR ;remember where host table begins
RELEAS
POPJ 17,
MAPHS3: MOVEI 2,400000 ;place to put host table, beginning of upper
ADDI 0,(2) ;ending address of table
MOVEM 0,HSTTOP ;end of table
CORE2 0, ;get enough core in upper segment
JRST 4,.-1
JRST MAPHS4
;⊗ HSTNUM HSTNUS HSTNU1
; HSTNUM -- Return descriptor block for a host
; Call: MOVEI <host number>
; PUSHJ 17,HSTNUM
; <error return--no such host>
; <return--absolute NAMNUM in 0, NUMSYS,,NUMNAM in 1, NUMBTS,,NUMMCH in 2>
; Smashes 0, 1, 2, 3, and 4.
HSTNUM: GETNET 4,0 ; get network number
SKIPN 4
TLO 0,(NW%ARP) ; if none given, assume ARPANet
MOVE 1,HSTADR
MOVE 1,NETPTR(1)
PUSHJ 17,HSTNUS ; lookup network number
POPJ 17,
MOVE 1,NTRTAB(1) ; get address table for network
MOVEM 4 ; thing to search for
PUSHJ 17,HSTNUS ; lookup address
POPJ 17,
HLRZ 7,ADLSIT(1) ; get site table entry
ADD 7,HSTADR
JRST CPOPJ1
HSTNUS: ADD 1,HSTADR ; relocate table
MOVE 2,(1) ; get # of entries
MOVE 3,1(1) ; and entry size
ADDI 1,2 ; point at first entry
HSTNU1: CAMN 4,(1) ; found it?
JRST CPOPJ1 ; yes, skip return for success
ADD 1,3 ; point at next entry
SOJG 2,HSTNU1 ; keep on searching
POPJ P, ; failed
;⊗ SWINIR SWINR1 SWINR2 SWINIP SWINP1 PRHNUM PRHNIP PRDECP PRDEC PROCT PRLOOP PDL MONCMP NOHOST PASS1 EXACT HSTADR HSTTOP HSTEXT CRLF CPOPJ2 CPOPJ1 CPOPJ
;Some of these subroutines adapted from TELNET.FAI[S,NET].
; Super winning numeric input routine. Numbers are parsed as both octal and
; decimal, unless either (a) an 8 or 9 appears in the number, or (b) the number
; is followed by a decimal point.
SWINIR: SETZB A,B ; A ← octal number, B ← decimal
SWINR1: CAIL X,"8" ; if can't be octal, A ← -1
SETO A,
JUMPL A,SWINR2
LSH A,3
ADDI A,-"0"(X) ; bring in next octal digit
SWINR2: IMULI B,=10
ADDI B,-"0"(X) ; bring in next decimal digit
ILDB X,Y
CAIN X,"." ; decimal point ends spec and forces decimal
JRST [ SETO A,
ILDB X,Y
POPJ P,]
CAIL X,"0"
CAILE X,"9"
POPJ P, ; non-numeric, return
JRST SWINR1
;Super winning IP host number parser. If an IP host number is seen, then it will
;be returned in B and SWINIP will skip return. Otherwise, just like SWINIR.
SWINIP: PUSHJ P,SWINIR ;Parse a number
CAIL X,"0" ;Check the next character
CAILE X,"9"
POPJ P, ;Not a digit, so not an IP host number
PUSH P,B ;Save 1st byte
PUSHJ P,SWINP1 ;Get rest of IP host number left-adj in B
POP P,A ;Restore 1st byte
LSHC A,-=12 ;Right-adjust entire number in B
JRST CPOPJ1 ;Skip to show IP host number
;Subroutine to return an IP host number left-adjusted in B.
SWINP1: PUSHJ P,SWINIR ;Get a number
PUSH P,B ;Save it
CAIL X,"0" ;See if a digit follows
CAILE X,"9"
TDZA B,B ;No. Zero B and skip
PUSHJ P,SWINP1 ;Yes, get rest of IP host in B
POP P,A ;Get back current byte
LSHC A,-=8 ;Shift into rest of number
POPJ P,
;Routine to print a host number, either in SU Ethernet or IP format. Takes
;host number in X.
PRHNUM: TLNE X,740000 ;Non-Internet?
JRST PRHNIP ;Yes, print non-IP
LDB A,[POINT 8,X,11]
PUSHJ P,PRDEC ;Print first byte
LDB A,[POINT 8,X,19]
PUSHJ P,PRDECP ;Print period and second byte
LDB A,[POINT 8,X,27]
PUSHJ P,PRDECP ;Print period and third byte
LDB A,[POINT 8,X,35]
PUSHJ P,PRDECP ;Print period and fourth byte
POPJ P,
PRHNIP: HLRZ A,X ;Get left half of addr
CAIE A,(NW%SU) ;SU-Net?
POPJ P, ;No, return quietly
OUTSTR [ASCIZ/SU /]
LDB A,[POINT 8,X,27]
PUSHJ P,PROCT ;Print first byte
OUTCHR ["#"]
LDB A,[POINT 8,X,35]
PUSHJ P,PROCT ;Print second byte
POPJ P,
PRDECP: OUTCHR ["."]
PRDEC: SKIPA C,[=10]
PROCT: MOVEI C,10
PRLOOP: IDIV A,C
PUSH P,B
SKIPE A
PUSHJ P,PRLOOP
POP P,A
ADDI A,"0"
OUTCHR A
POPJ P,
PDL: BLOCK PDLEN
MONCMP: BLOCK 1 ;-1 → got a monitor command
NOHOST: BLOCK 1 ;-1 → no host found so far
PASS1: BLOCK 1 ;-1 → in pass 1 of 2-pass search
EXACT: BLOCK 1 ;-1 → got an exact match
HSTADR: BLOCK 1
HSTTOP: BLOCK 1
HSTEXT: BLOCK 25
CRLF: BYTE (7)15,12
CPOPJ2: AOS (P)
CPOPJ1: AOS (P)
CPOPJ: POPJ P,
END START